#include "App_LumbarSupport.h"

// 定义腰托结构体数组
LumbarSupport lumbarSupports[LUMBAR_SUPPORT_MAXSIZE] = {
    [YT_INDEX_UP]     = { YT_STATE_IDLE, 0, FULL_PRESSURE_TIME_VALUE },
    [YT_INDEX_MIDDLE] = { YT_STATE_IDLE, 0, FULL_PRESSURE_TIME_VALUE },
    [YT_INDEX_DOWN]   = { YT_STATE_IDLE, 0, FULL_PRESSURE_TIME_VALUE },
};

// 阀门映射表
typedef struct
{
    YTIndex_e      index;
    SolenoidValve *inflateValve;
    SolenoidValve *deflateValve;
} ValveMapping;

static const ValveMapping valveMap[] = {
    { YT_INDEX_UP, &solenoidValveList[SOLENOID_VALVE_TYPE_YT3],
      &solenoidValveList[SOLENOID_VALVE_TYPE_YTR3] },
    { YT_INDEX_MIDDLE, &solenoidValveList[SOLENOID_VALVE_TYPE_YT4],
      &solenoidValveList[SOLENOID_VALVE_TYPE_YTR4] },
    { YT_INDEX_DOWN, &solenoidValveList[SOLENOID_VALVE_TYPE_YT5],
      &solenoidValveList[SOLENOID_VALVE_TYPE_YTR5] },
};

/**
 * @brief 初始化腰托
 */
void App_LumbarSupport_Init(void)
{
    Inf_SolenoidValve_Init();
    Inf_Pump_Init();
    Driver_BSTIM32_Init();
}

/**
 * @brief 设置指定腰托为充气状态并执行充气
 *
 * @param YTIndex 腰托索引
 */
void App_LumbarSupport_StartInflation(YTIndex_e YTIndex)
{
    if (YTIndex >= YT_INDEX_MAXSIZE) return;

    LumbarSupport *yt = &lumbarSupports[YTIndex];

    if (yt->state != YT_STATE_INFLATION && yt->inflatedTime < yt->fullPressure) {
        yt->state = YT_STATE_INFLATION;
        App_LumbarSupport_AirInflation(YTIndex);
    }
}

/**
 * @brief 设置指定腰托为泄气状态并执行泄气
 *
 * @param YTIndex 腰托索引
 */
void App_LumbarSupport_StartDeflation(YTIndex_e YTIndex)
{
    if (YTIndex >= YT_INDEX_MAXSIZE) return;

    LumbarSupport *yt = &lumbarSupports[YTIndex];

    if (yt->state != YT_STATE_DEFLATION) {
        yt->state = YT_STATE_DEFLATION;
        App_LumbarSupport_AirDeflate(YTIndex);
    }
}

/**
 * @brief 设置指定腰托为充气状态
 *
 * @param YTIndex 腰托索引
 */
void App_LumbarSupport_AirInflation(YTIndex_e YTIndex)
{
    if (YTIndex >= YT_INDEX_MAXSIZE) return;

    LumbarSupport *yt = &lumbarSupports[YTIndex];

    if (yt->state != YT_STATE_INFLATION) return;
    if (yt->inflatedTime >= yt->fullPressure) return;

    // 开启电磁阀开关 和 泵
    if (!solenoidValveSwitchIsOn) {
        Inf_SolenoidValve_EnableSwitch();
    }
    if (!pumpIsOn) {
        Inf_Pump_Enable();
    }

    // 控制电磁阀
    for (uint8_t i = 0; i < sizeof(valveMap) / sizeof(valveMap[0]); i++) {
        if (valveMap[i].index == YTIndex) {
            Inf_SolenoidValve_ActivateSolenoidValve(valveMap[i].inflateValve);
            Inf_SolenoidValve_DeactivateSolenoidValve(valveMap[i].deflateValve);
            break;
        }
    }
}

/**
 * @brief 设置指定腰托为泄气状态
 *
 * @param YTIndex 腰托索引
 */
void App_LumbarSupport_AirDeflate(YTIndex_e YTIndex)
{
    if (YTIndex >= YT_INDEX_MAXSIZE) return;

    LumbarSupport *yt = &lumbarSupports[YTIndex];

    if (yt->state != YT_STATE_DEFLATION) return;

    // // TODO: 如果需要泵运行，请取消注释
    // if (!pumpIsOn) {
    //     Inf_Pump_Enable();
    // }

    for (uint8_t i = 0; i < sizeof(valveMap) / sizeof(valveMap[0]); i++) {
        if (valveMap[i].index == YTIndex) {
            Inf_SolenoidValve_ActivateSolenoidValve(valveMap[i].deflateValve);
            Inf_SolenoidValve_DeactivateSolenoidValve(valveMap[i].inflateValve);
            break;
        }
    }
}

/**
 * @brief 所有腰托停止运行
 */
void App_LumbarSupport_AllYTValvesStopped(void)
{
    if (pumpIsOn) {
        Inf_Pump_Disable();
    }

    for (int i = 0; i < LUMBAR_SUPPORT_MAXSIZE; i++) {
        LumbarSupport *yt = &lumbarSupports[i];
        if (yt->state != YT_STATE_IDLE) {
            yt->state = YT_STATE_IDLE;
            for (int j = 0; j < sizeof(valveMap) / sizeof(valveMap[0]); j++) {
                if (valveMap[j].index == i) {
                    Inf_SolenoidValve_DeactivateSolenoidValve(valveMap[j].inflateValve);
                    Inf_SolenoidValve_DeactivateSolenoidValve(valveMap[j].deflateValve);
                    break;
                }
            }
        }
    }
}

/**
 * @brief 中间腰托充气，上下泄气
 */
void App_LumbarSupport_PrevAdjust(void)
{
    LumbarSupport *mid = &lumbarSupports[YT_INDEX_MIDDLE];

    if (mid->inflatedTime == mid->fullPressure) {
        Inf_SolenoidValve_DeactivateSolenoidValve(&solenoidValveList[SOLENOID_VALVE_TYPE_YT4]);
        if (pumpIsOn) {
            Inf_Pump_Disable();
        }
    }

    App_LumbarSupport_StartInflation(YT_INDEX_MIDDLE);
    App_LumbarSupport_StartDeflation(YT_INDEX_UP);
    App_LumbarSupport_StartDeflation(YT_INDEX_DOWN);
}

/**
 * @brief 上部腰托充气，中下泄气
 */
void App_LumbarSupport_UpAdjust(void)
{
    LumbarSupport *up = &lumbarSupports[YT_INDEX_UP];
    if (up->inflatedTime == up->fullPressure) {
        Inf_SolenoidValve_DeactivateSolenoidValve(&solenoidValveList[SOLENOID_VALVE_TYPE_YT3]);
        if (pumpIsOn) {
            Inf_Pump_Disable();
        }
    }

    App_LumbarSupport_StartInflation(YT_INDEX_UP);
    App_LumbarSupport_StartDeflation(YT_INDEX_MIDDLE);
    App_LumbarSupport_StartDeflation(YT_INDEX_DOWN);
}

/**
 * @brief 下部腰托充气，中上泄气
 */
void App_LumbarSupport_DownAdjust(void)
{
    LumbarSupport *down = &lumbarSupports[YT_INDEX_DOWN];
    LOG("down->inflatedTime: %d\n", down->inflatedTime);
    if (down->inflatedTime == down->fullPressure) {
        Inf_SolenoidValve_DeactivateSolenoidValve(&solenoidValveList[SOLENOID_VALVE_TYPE_YT5]);
        if (pumpIsOn) {
            Inf_Pump_Disable();
        }
    }

    App_LumbarSupport_StartInflation(YT_INDEX_DOWN);
    App_LumbarSupport_StartDeflation(YT_INDEX_MIDDLE);
    App_LumbarSupport_StartDeflation(YT_INDEX_UP);
}

/**
 * @brief 所有腰托泄气
 */
void App_LumbarSupport_BehindAdjust(void)
{
    if (pumpIsOn) {
        Inf_Pump_Disable();
    }

    for (int i = 0; i < LUMBAR_SUPPORT_MAXSIZE; i++) {
        App_LumbarSupport_StartDeflation((YTIndex_e)i);
    }
}
